﻿using NewfarTormentTool.core;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;

namespace NewfarTormentTool.data
{
    /// <summary>
    /// 数据存储
    /// </summary>
    public class RoleDataStorage
    {
        private static RoleDataStorage instance;
        public static RoleDataStorage Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new RoleDataStorage();
                }
                return instance;
            }
        }

        /// <summary>
        /// 所有角色配置
        /// </summary>
        public Dictionary<int, RoleConfig> Configs = new Dictionary<int, RoleConfig>();
        /// <summary>
        /// 用户预存数据
        /// </summary>
        public Dictionary<string, UserRecord> Records = new Dictionary<string, UserRecord>();
        /// <summary>
        /// 当前用户
        /// </summary>
        public string CurUser = null;
        /// <summary>
        /// 用户角色情况
        /// </summary>
        public Dictionary<int, UserRole> UserRoles = new Dictionary<int, UserRole>();
        /// <summary>
        /// 主界面
        /// </summary>
        public MainForm Main = null;

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            LoadConfigs();
            LoadRecords();
            LoadUserRoles(null);
        }

        /// <summary>
        /// 加载配置数据
        /// </summary>
        private void LoadConfigs()
        {
            string fileFullName = Path.Combine(Directory.GetCurrentDirectory(), "config", "role_config.json");
            if (!File.Exists(fileFullName))
            {
                return;
            }
            RoleConfig[] cc = JsonSerializer.Deserialize<RoleConfig[]>(File.ReadAllText(fileFullName));
            if (cc == null)
            {
                return;
            }
            foreach (RoleConfig config in cc)
            {
                Configs[config.id] = config;
            }
        }

        /// <summary>
        /// 加载预存数据
        /// </summary>
        private void LoadRecords()
        {
            string fileFullName = Path.Combine(Directory.GetCurrentDirectory(), "config", "user_record.json");
            if (!File.Exists(fileFullName))
            {
                return;
            }
            UserRecord[] rr = JsonSerializer.Deserialize<UserRecord[]>(File.ReadAllText(fileFullName));
            if (rr == null)
            {
                return;
            }
            foreach (UserRecord record in rr)
            {
                Records[record.user] = record;
            }
        }

        /// <summary>
        /// 加载玩家角色
        /// </summary>
        /// <param name="user">玩家名(null)</param>
        public void LoadUserRoles(string user)
        {
            List<int> actives;
            if (user == null || !Records.ContainsKey(user))
            {
                actives = new List<int>();
            }
            else
            {
                actives = Records[user].actives;
            }
            UserRoles.Clear();
            foreach (RoleConfig conf in Configs.Values)
            {
                UserRole role = new UserRole()
                {
                    Config = conf,
                    Active = actives.Contains(conf.id),
                };
                if (UserRoles.ContainsKey(conf.id))
                {
                    throw new Exception("Error! Repeat id=" + conf.id);
                }
                UserRoles[conf.id] = role;
            }
        }

        /// <summary>
        /// 排序角色
        /// </summary>
        public List<UserRole> RolesInRow()
        {
            List<UserRole> ret = new List<UserRole>(UserRoles.Values);
            ret.Sort((ur1, ur2) => ur1.Config.id.CompareTo(ur2.Config.id));
            return ret;
        }

        /// <summary>
        /// 变更角色激活
        /// </summary>
        public void ChangeUserRoleActive(int id, bool active)
        {
            bool exsit = UserRoles.TryGetValue(id, out var role);
            if (exsit)
            {
                role.Active = active;
            }
            if (Main != null)
            {
                Main.RefreshSaveButton();
            }
        }

        /// <summary>
        /// 随机角色
        /// </summary>
        /// <param name="num">数量</param>
        public List<UserRole> RandomRoles(int num)
        {
            List<UserRole> actives = new List<UserRole>(UserRoles.Values.Where(r => r.Active));
            if (actives.Count < num)
            {
                return new List<UserRole>();
            }
            actives = actives.OrderBy(r => Guid.NewGuid()).ToList();
            return actives.GetRange(0, num);
        }

        /// <summary>
        /// 是否有修改
        /// </summary>
        public bool Changed()
        {
            if (CurUser == null)
            {
                return true;
            }
            if (!Records.ContainsKey(CurUser))
            {
                return true;
            }
            UserRecord record = Records[CurUser];
            foreach (UserRole role in UserRoles.Values)
            {
                if (role.Active != record.actives.Contains(role.Config.id))
                {
                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 添加或更新用户记录
        /// </summary>
        /// <param name="user">用户</param>
        /// <param name="record">记录</param>
        public void AddOrUpdateRecord(string user, UserRecord record)
        {
            if (user == null || record == null)
            {
                return;
            }
            Records[user] = record;
            SaveAll();
        }

        /// <summary>
        /// 存储
        /// </summary>
        public void SaveAll()
        {
            UserRecord[] records = Records.Values.ToArray();
            JsonSerializerOptions options = new JsonSerializerOptions()
            {
                WriteIndented = true,
            };
            string fileFullName = Path.Combine(Directory.GetCurrentDirectory(), "config", "user_record.json");
            string fileText = JsonSerializer.Serialize(records, options);
            File.WriteAllText(fileFullName, fileText);
        }
    }
}
